module aib_mac_qua_tb;
    localparam MW = 160;
    localparam DW = 128;

    reg nclk;
    reg mclk;
    reg rst;
    wire [MW-1:0] l_data_in_f;
    wire [MW-1:0] l_data_out_f;
    wire [MW-1:0] r_data_in_f;
    wire [MW-1:0] r_data_out_f;
    wire [DW-1:0] l_i_data0;
    wire l_i_valid0;
    wire l_o_yummy0;
    wire [DW-1:0] l_o_data0;
    wire l_o_valid0;
    wire l_i_yummy0;
    wire [DW-1:0] l_i_data1;
    wire l_i_valid1;
    wire l_o_yummy1;
    wire [DW-1:0] l_o_data1;
    wire l_o_valid1;
    wire l_i_yummy1;
    wire [DW-1:0] r_i_data0;
    wire r_i_valid0;
    wire r_o_yummy0;
    wire [DW-1:0] r_o_data0;
    wire r_o_valid0;
    wire r_i_yummy0;
    wire [DW-1:0] r_i_data1;
    wire r_i_valid1;
    wire r_o_yummy1;
    wire [DW-1:0] r_o_data1;
    wire r_o_valid1;
    wire r_i_yummy1;

    aib_pair_behav #(
        .MW (MW )
    ) u_aib_pair_behav(
        .clk          (mclk         ),
        .rst          (rst          ),
        .l_data_in_f  (l_data_in_f  ),
        .l_data_out_f (l_data_out_f ),
        .r_data_in_f  (r_data_in_f  ),
        .r_data_out_f (r_data_out_f )
    );

    aib_mac_qua #(
        .DW (DW ),
        .MW (MW )
    ) l_aib_mac_qua(
        .mclk(mclk),
        .nclk(nclk),
        .rst        (rst        ),
        .data_in_f  (l_data_in_f ),
        .data_out_f (l_data_out_f ),
        .i_data0    (l_i_data0    ),
        .i_valid0   (l_i_valid0   ),
        .o_yummy0   (l_o_yummy0   ),
        .o_data0    (l_o_data0    ),
        .o_valid0   (l_o_valid0   ),
        .i_yummy0   (l_i_yummy0   ),
        .i_data1    (l_i_data1    ),
        .i_valid1   (l_i_valid1   ),
        .o_yummy1   (l_o_yummy1   ),
        .o_data1    (l_o_data1    ),
        .o_valid1   (l_o_valid1   ),
        .i_yummy1   (l_i_yummy1   )
    );

    aib_mac_qua #(
        .DW (DW ),
        .MW (MW )
    ) r_aib_mac_qua(
    	.mclk(mclk),
        .nclk(nclk),
        .rst        (rst        ),
        .data_in_f  (r_data_in_f  ),
        .data_out_f (r_data_out_f ),
        .i_data0    (r_i_data0    ),
        .i_valid0   (r_i_valid0   ),
        .o_yummy0   (r_o_yummy0   ),
        .o_data0    (r_o_data0    ),
        .o_valid0   (r_o_valid0   ),
        .i_yummy0   (r_i_yummy0   ),
        .i_data1    (r_i_data1    ),
        .i_valid1   (r_i_valid1   ),
        .o_yummy1   (r_o_yummy1   ),
        .o_data1    (r_o_data1    ),
        .o_valid1   (r_o_valid1   ),
        .i_yummy1   (r_i_yummy1   )
    );
    initial begin
        $dumpfile("aib_mac_qua_tb.vcd");
        $dumpvars;
        $display("[('l0i','r0o'),('l1i','r1o'),('r0i','l0o'),('r1i','l1o')]");
        mclk=1;
        forever #5 mclk=~mclk;
    end
    initial begin
        nclk=1;
        forever #7 nclk=~nclk;
    end
    initial begin
        rst=1;
        repeat(4) @(posedge mclk);
        @(posedge nclk);
        @(negedge mclk);
        rst=0;
    end
    // timeout 1000 periods
    initial begin
        repeat(100) @(posedge nclk);
            $display("timeout");
            $finish;
    end

    localparam IR = 70;
    localparam ER = 50;
    router_behav #(
        .IR (IR ),
        .ER (ER )
    ) router_behav_l00(
        .clk     (nclk     ),
        .rst     (rst     ),
        .o_valid (l_i_valid0 ),
        .o_data  (l_i_data0  ),
        .i_yummy (l_o_yummy0 ),
        .i_valid (l_o_valid0 ),
        .i_data  (l_o_data0  ),
        .o_yummy (l_i_yummy0 )
    );


    router_behav #(
        .IR (IR ),
        .ER (ER )
    ) router_behav_l01(
        .clk     (nclk     ),
        .rst     (rst     ),
        .o_valid (l_i_valid1 ),
        .o_data  (l_i_data1  ),
        .i_yummy (l_o_yummy1 ),
        .i_valid (l_o_valid1 ),
        .i_data  (l_o_data1  ),
        .o_yummy (l_i_yummy1 )
    );

    router_behav #(
        .IR (IR ),
        .ER (ER )
    ) router_behav_r00(
        .clk     (nclk     ),
        .rst     (rst     ),
        .o_valid (r_i_valid0 ),
        .o_data  (r_i_data0  ),
        .i_yummy (r_o_yummy0 ),
        .i_valid (r_o_valid0 ),
        .i_data  (r_o_data0  ),
        .o_yummy (r_i_yummy0 )
    );


    router_behav #(
        .IR (IR ),
        .ER (ER )
    ) router_behav_r01(
        .clk     (nclk     ),
        .rst     (rst     ),
        .o_valid (r_i_valid1 ),
        .o_data  (r_i_data1  ),
        .i_yummy (r_o_yummy1 ),
        .i_valid (r_o_valid1 ),
        .i_data  (r_o_data1  ),
        .o_yummy (r_i_yummy1 )
    );

    // TEMPLATE
    always @(posedge nclk) begin
        if(l_i_valid0)
            $display("%t:l0i:%h",$time,l_i_data0);
        if(l_o_valid0)
            $display("%t:l0o:%h",$time,l_o_data0);
    end
    always @(posedge nclk) begin
        if(l_i_valid1)
            $display("%t:l1i:%h",$time,l_i_data1);
        if(l_o_valid1)
            $display("%t:l1o:%h",$time,l_o_data1);
    end
    always @(posedge nclk) begin
        if(r_i_valid0)
            $display("%t:r0i:%h",$time,r_i_data0);
        if(r_o_valid0)
            $display("%t:r0o:%h",$time,r_o_data0);
    end
    always @(posedge nclk) begin
        if(r_i_valid1)
            $display("%t:r1i:%h",$time,r_i_data1);
        if(r_o_valid1)
            $display("%t:r1o:%h",$time,r_o_data1);
    end

endmodule

